package api

import (
	"fmt"

	"gitee.com/go-kade/go12/vblog/apps/blog"
	"gitee.com/go-kade/go12/vblog/apps/token"
	"gitee.com/go-kade/go12/vblog/apps/user"
	"gitee.com/go-kade/go12/vblog/common"
	"gitee.com/go-kade/go12/vblog/exception"
	"gitee.com/go-kade/go12/vblog/middlewares"
	"gitee.com/go-kade/go12/vblog/response"
	"github.com/gin-gonic/gin"
)

// 需要把HandleFunc 添加到Root路由，定义 API ---> HandleFunc
// 可以选择把这个Handler上的HandleFunc都注册到路由上面
func (h *BlogApiHeadler) Registry(r gin.IRouter) {
	// r 是gin的路由器
	v1 := r.Group("v1").Group("blogs")
	v1.GET("/", h.QueryBlog)
	// GET /api/v1/blogs/43
	// url路径里面有变量: :id, 什么一个路径变量, r.Params("id") 43
	// /:id ---? /43   id = 43  11
	//api/v1/bLogs/43
	v1.GET("/:id", h.DescribeBlog)

	// 后台管理接口 需要认证  这个有个规范，必须把需要修改的请求放在下面
	v1.Use(middlewares.NewTokenAuther().Auth)

	// POST /api/v1/blogs/
	v1.POST("/", middlewares.Required(user.ROLE_AUTHOR|user.ROLE_ADMIN|user.ROLE_AUDITOR), h.CreateBlog) //v1.POST("/", h.CreateBlog,middlewares.NewTokenAuther().Auth)

	//api/v1/bLogs/43
	v1.DELETE("/:id", middlewares.Required(user.ROLE_AUTHOR), h.DeleteBlog)

	//全量更新
	v1.PUT("/:id", middlewares.Required(user.ROLE_AUTHOR), h.UpdatePutBlog)

	v1.POST("/:id/audit", middlewares.Required(user.ROLE_AUDITOR), h.AuditBlog)

	//1.v1.Use(middlewares.NewTokenAuther().Auth)
	//2.middlewares.Required(user.ROLE_AUTHOR)
}

// 博客创建
func (h *BlogApiHeadler) CreateBlog(g *gin.Context) {
	//从Gin 请求上下文中： c.Keys， 获取认证过后的鉴权结果
	tkobj := g.Keys[token.TOKEN_GIN_KEY_NAME]
	tkobj1 := tkobj.(*token.Token)
	createBlog := blog.NewCreateBlogRequest()
	err := g.BindJSON(createBlog) //用户传进来的参数
	if err != nil {
		response.Failed(g, err)
	}
	// 充上下文中补充 用户信息
	createBlog.CreateByName = tkobj1.UserName
	ins, err := h.svc.CreateBlog(g.Request.Context(), createBlog)
	if err != nil {
		response.Failed(g, err)
	}
	response.Success(g, ins)
}

// 列表查询
func (h *BlogApiHeadler) QueryBlog(g *gin.Context) {
	createBlog := blog.NewQueryBlogRequest()
	createBlog.Keywords = g.Query("keywords")
	createBlog.ParsePageSize(g.Query("page_size"))
	createBlog.ParsePageNumber(g.Query("page_number"))
	switch g.Query("status") {
	case "draft":
		createBlog.SetStatus(blog.STATUS_DRAFT)
	case "published":
		createBlog.SetStatus(blog.STATUS_PUBLISHED)
	}

	set, err := h.svc.QueryBlog(g.Request.Context(), createBlog)
	if err != nil {
		response.Failed(g, err)
		return
	}

	response.Success(g, set)

}

// 详情查询
// GET /api/v1/blogs/43
func (h *BlogApiHeadler) DescribeBlog(g *gin.Context) {
	describeBlog := blog.NewDescribeBlogRequest(g.Param("id"))
	ins, err := h.svc.DescribeBlog(g.Request.Context(), describeBlog)
	if err != nil {
		response.Failed(g, err)
		return
	}

	response.Success(g, ins)
}

// 全量更新
// PUT /api/v1/blogs/43
// BODY  {}
func (h *BlogApiHeadler) UpdatePutBlog(g *gin.Context) {
	updateBlog := blog.NewPutUpdateBlogRequest(g.Param("id"))
	err := g.BindJSON(updateBlog.CreateBlogRequest)
	if err != nil {
		response.Failed(g, err)
		return
	}
	//1
	tkObj := g.Keys[token.TOKEN_GIN_KEY_NAME]
	if tkObj == nil {
		response.Failed(g, exception.NewNotFound("token not found"))
		return
	}
	tk, ok := tkObj.(*token.Token)
	if !ok {
		response.Failed(g, exception.NewNotFound("token not an *token.Token"))
		return
	}

	updateBlog.Scope = &common.Scope{
		UserId:       fmt.Sprintf("%d", tk.UserID),
		CreateByName: fmt.Sprintf(tk.UserName),
	}
	//1只能更新自己的不能更新别人的

	ins, err := h.svc.UpdateBlog(g.Request.Context(), updateBlog)
	if err != nil {
		response.Failed(g, err)
		return
	}
	response.Success(g, ins)
}

// 增量更新
// PATCH /api/v1/blogs/43
func (h *BlogApiHeadler) UpdatePatchBlog(g *gin.Context) {
	// 判断下用户是否登录(Token)
	// 判断当前用户是谁 UserA
	// 再判断UserA能不能删除这个Blog
	patchUpdateBlog := blog.NewPatchUpdateBlogRequest(g.Param("id"))
	err := g.BindJSON(patchUpdateBlog.CreateBlogRequest)
	if err != nil {
		response.Failed(g, err)
		return
	}
	ins, err := h.svc.UpdateBlog(g.Request.Context(), patchUpdateBlog)
	if err != nil {
		response.Failed(g, err)
		return
	}
	response.Success(g, ins)
}

// 删除id的博客
// DELETE /api/v1/blogs/43
func (h *BlogApiHeadler) DeleteBlog(g *gin.Context) {
	describeBlog := blog.NewDeleteBlogRequest(g.Param("id"))
	err := h.svc.DeleteBlog(g.Request.Context(), describeBlog)
	if err != nil {
		response.Failed(g, err)
		return
	}

	response.Success(g, "ok")
}

// 审核该文章 是否合法
// POST /api/v1/blogs/43/audit
func (h *BlogApiHeadler) AuditBlog(c *gin.Context) {
	in := blog.NewAuditBlogRequest(c.Param("id"))
	err := c.BindJSON(in)
	if err != nil {
		response.Failed(c, err)
		return
	}

	ins, err := h.svc.AuditBlog(c.Request.Context(), in)
	if err != nil {
		response.Failed(c, err)
		return
	}

	response.Success(c, ins)
}
